package cn.hinglo.gameclaw.alipay.utils;

import cn.hinglo.gameclaw.alipay.config.WeixinConfig;
import cn.hutool.json.JSONUtil;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * @createTime: 2018/5/23
 * @author: HingLo
 * @description: 微信充值处理
 */
public class WeixinUtils {
    /**
     * 统一下单
     *
     * @param data 下单数据
     * @return 返回订单信息
     * @throws Exception
     */
    public static String order(Map<String, String> data) throws Exception {
        WeixinConfig config = WeixinConfig.getInstance();
        WXPay wxpay = new WXPay(config);
        //返回的下单信息
        Map<String, String> resp = wxpay.unifiedOrder(data);
        //进行二次签名
        Map<String, String> map = sign(resp);
        //签名
        String sign = WXPayUtil.generateSignature(map, config.getKey());
        map.put("sign", sign);
        return JSONUtil.parseFromMap(map).toString();
    }

    /**
     * 微信支付结果通知验证
     *
     * @param request request
     * @return 成功后的map数据
     * @throws Exception
     */
    public static Map<String, String> validate(HttpServletRequest request) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String notifyData = getBodyString(reader);
        WeixinConfig config = WeixinConfig.getInstance();
        WXPay wxpay = new WXPay(config);
        // 转换成map
        Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);
        if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
            // 签名正确
            // 进行处理。
            // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户侧订单状态从退款改成支付成功
            return notifyMap;
        } else {
            // 签名错误，如果数据里没有sign字段，也认为是签名错误
            return null;
        }
    }

    /**
     * 获取body中的数据
     *
     * @param br br
     * @return xml 数据
     */
    private static String getBodyString(BufferedReader br) {
        String inputLine;
        String str = "";
        try {
            while ((inputLine = br.readLine()) != null) {
                str += inputLine;
            }
            br.close();
        } catch (IOException e) {
            System.out.println("IOException: " + e);
        }
        return str;
    }

    private static Map<String, String> sign(Map<String, String> map) {
        Map<String, String> secondSign = new HashMap<>(6);
        secondSign.put("appid", map.get("appid"));
        secondSign.put("noncestr", map.get("nonce_str"));
        secondSign.put("partnerid", map.get("mch_id"));
        secondSign.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        secondSign.put("package", "Sign=WXPay");
        secondSign.put("prepayid", map.get("prepay_id"));
        return secondSign;

    }
}
